package com.bionic.banking.core.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

public class Currency implements Serializable, Comparable {

    private Integer code;
    private String symbol;
    private String name;
    private String fullname;

    private Currency() {
    }

    public Currency(Integer code, String symbol) {
        this.code = code;
        this.symbol = symbol;
    }

    public Currency(Integer code, String symbol, String name) {
        this.code = code;
        this.symbol = symbol;
        this.name = name;
    }

    public Currency(Integer code, String symbol, String name, String displayname) {
        this.code = code;
        this.symbol = symbol;
        this.name = name;
        this.fullname = displayname;
    }

    public Integer getCode() {
        return code;
    }

    public String getSymbol() {
        return symbol;
    }

    public String getName() {
        return name;
    }

    public String getFullName() {
        return fullname;
    }
    
    /*
     * getSymbol(), getSymbol(Locale loc) - return '$', etc
     * getDisplayName(),  getDisplayName(Locale locale) 
     * getNumericCode()
     * toString() - returns currencyCode
     */
    private static List<Currency> currencies = null;

    public static List<Currency> getCurrencies() {

        if (currencies == null) {
            currencies = new ArrayList<Currency>();

            Locale[] locs = Locale.getAvailableLocales();
            for (Locale loc : locs) {
                try {                    
                    java.util.Currency sysCurrency = java.util.Currency.getInstance(loc);
                    // don't use unavailable currencies
                    //if (!availCodes.contains(sysCurrency.getCurrencyCode())) {
                    //    continue;
                    //}
                    Integer code = sysCurrency.getNumericCode();
                    String shortName = sysCurrency.getCurrencyCode();
                    String symbol = sysCurrency.getSymbol(loc).trim();
                    String displayname = sysCurrency.getDisplayName(loc);

                    Currency currencyEntity = new Currency(code, symbol, shortName, displayname);
                    if (!currencies.contains(currencyEntity)) {
                        currencies.add(currencyEntity);
                    }

                } catch (Exception ex) {
                    // Locale not found
                }
                Collections.sort(currencies);
            }
        }

        return currencies;
    }

    public static Currency getByCode(Integer code) {

        for (Currency currency : getCurrencies()) {
            if (currency.code.equals(code)) {
                return currency;
            }
        }
        return null;
    }

    public static Currency getBySymbol(String symbol) {

        for (Currency currency : getCurrencies()) {
            if (currency.symbol.equals(symbol)) {
                return currency;
            }
        }

        return null;
    }

    public static Currency getByName(String name) {

        for (Currency currency : getCurrencies()) {
            if (currency.name.equals(name)) {
                return currency;
            }
        }
        return null;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (code != null ? code.hashCode() : 0);

        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Currency)) {
            return false;
        }
        Currency other = (Currency) object;

        return this.code.equals(other.code);
    }

    @Override
    public String toString() {

        String signature = name + " (" + symbol + ")";
        return signature;
    }

    @Override
    public int compareTo(Object o) {
        if (!(o instanceof Currency)) {
            return -1;
        }
        Currency other = (Currency) o;

        return this.symbol.compareToIgnoreCase(other.symbol);
    }
}
